查看原文
其他

【程序猿】手把手教你做3D扫雷:完结篇

2017-01-10 风吹蛋微凉 Gad-腾讯游戏开发者平台


在这个系列的最后,我们将实现扫雷游戏点击网格功能,让我们的游戏更具可玩性。我们还要实现玩家能够赢得或输掉游戏的功能。如果你完成之前的教程,游戏现在应该就能够创建格子的区域,然后随机地把炸弹赋值给他们。当玩家用鼠标在格子上划过就会出现高亮效果,还能够放置和移除旗子。每个格子之间还能够通信,还能够计算出附近的炸弹数。


揭开格子


我们已经添加了右键点击防止旗子的功能,现在,让我们添加左键揭开格子的功能。在OnMouseOver函数中,我们需要引用鼠标左击的方法。代码如下:



当鼠标左键点击时,UncoverTile函数将被调用。确保你创建了这个方法,这样才不会出Bug!


如果运行成功了,我们需要声明一个新的材质。



创建区别于基础色的颜色。就比如你的基础色为蓝色,你就应该选择绿色代表已经揭开的状态。千万别选择红色,因为接下来我们会用这个颜色表示揭开炸弹后的状态。当我们调用这个函数后,会发生如下事情:


  · 第一步会检查格子是否确实有炸弹;


  · 如果没有炸弹,这个区域便会被设置为uncovered状态,激活文本显示状态,向我们显示周围炸弹数,然后设置uncovered材质;


  · 接着,格子不能够被点击第二次,也不会重复高亮,这就意味着格子响应事件只会在鼠标真正点击之后发生。


  在我们运行测试前,我们需要确保当鼠标滑过并离开格子后材质不会被改变。为了实现这个,我们需要调整OnMouseExit函数,如下:



这样,如果格子没有被揭开,颜色只会变成黑色。试一下呗!你应该能揭开格子了。现在,即便格子上有炸弹,也不会有反应。


 


让空的格子被间接发现


这是个难题。在扫雷游戏中,当你揭开一个格子时,挨着的空的格子就会被间接揭开,然后接着传开。这里考虑一下:


 


事实上我们看不到炸弹和数字,只有平常的格子:


 


当一个周围炸弹数为0的格子被揭开后,其周围的格子你会被自动揭开,然后传递给周围的格子。


 


新揭开的格子会检测他们周围的格子信息,如果周围的格子也没有炸弹,也会被自动揭开。


 


这样的传递会像波一样传递,直到临近的格子有炸弹才会停止传递。


 


这就能实现扫雷中出现的空白区域的情况。为了能够实现这一功能,我们需要两个方法:UncoverAdjacentTile和UncoverTileExternal。



我们还得更新一下UncoverTile函数:



当我们揭开一个格子,临近的格子中并没有炸弹,就会调用UncoverAdjacentTiles函数。然后就会检测附近的各自看看有没有炸弹。如果还是没有,就会自动揭开格子,然后进入下一轮的检测。如果附近有炸弹,就会只揭开当前的格子。我们需要进行小测试:为了能够容易出现空白区域,我们创建一个很大的区域9x9的81格子的游戏区域,这里只放置10个炸弹。


 


现在游戏就可以运行了,当然现在还不能触发炸弹,这个功能之后会实现的。


炸弹的触发


当我们揭开有炸弹的格子时,游戏就会结束,玩家也会输掉游戏。并且,其他所有的炸弹也会显示出来。为了实现这种效果,我们需要添加一个新的材质来表示爆炸的炸弹:



反正我建议使用红色表示炸弹爆炸。我们还需要另外两个方法去处理所有炸弹爆炸的效果:



我们在UncoverTile函数中调用上面两个方法:



如果格子内有炸弹,格子便会爆炸。Explode函数会发送“explode”给其他所有的炸弹,并且引爆他们。


 


赢得游戏


当所有含炸弹的格子被正确地标定好旗子后,游戏便胜利了。这时候,那些没有被揭开的格子也会被自动揭开。那么我们怎么才能检测到这些?


让我们先在Grid类中添加一个state变量,这样我们才能检测到游戏目前的状态(游戏中,输了,赢了)。



当我们处在某个游戏状态时,我们可以创建一个简单的GUI来呈现在屏幕上这些信息。我们可以用原生的GUI。



这个会告诉我们当前游戏所处状态,我们将这些状态分为inGame,gameOver和gameWon。我们也可以在Tile中检测,实现只有当前游戏状态为inGame后格子才能够响应。在OnMouseOver和OnMouseExit函数中,移除所有代码到一个if条件的代码块中,其判断条件为Grid.state是否为inGame,就像这样:



这里有两种方法检测游戏胜利:1.我们可以计算正确标记的炸弹的数量;2.我们还可以检测没有炸弹的格子是不是全都被揭开了。为了实现这个功能,我们需要一下变量,将他们添加到Grid类中:



别忘了在Start函数中将minesRemaining赋值给numberOfMines,其他的变量为0.Start函数如下:



最后一行设置了游戏的状态(这个在之后讲解restart函数中非常重要)。之后我们我们会在Update函数中检测游戏结束的条件:



我们可以通过改变状态为gameWon来结束游戏,揭开所有的格子,并且标记所有剩下的炸弹:



如果上面一切运行正常,我们还需要改下UncoverTile函数,如下:



UncoverTileExternal函数如下:



我们还需要根据旗子是否被准确放置,来调整minesMarkedCorrextly和minesRemaining的值:



输掉游戏


同样,我们还要设置输掉游戏的情况。我们可以在Explode函数中实现这个,在Explode添加如下代码:



当这个代码运行时,游戏的状态就转变成了gameOver,格子就不会再响应了:


给GUI添加更多的方法


之前的步骤中我们用了UGUI来告诉玩家他们当前所处的游戏状态。现在我们要扩展来展示更多信息。代码如下:



随着状态的改变,相应的信息就会在屏幕上显示出来。如果输掉游戏或者胜利,我们就能显示如下信息:



我们也可以显示被发现的炸弹数量,或者添加一个重置按钮:当游戏结束后,重新开始游戏。



你可以测试下最终版的扫雷!


 


总结


就这些了,我们就用Unity创建了一个属于你自己的扫雷游戏。我希望您能够喜欢这个教程,如果有任何问题,请在下面评论区留言。




点击一下立即阅读近期热文


手把手教你做3D扫雷:准备篇

《全境封锁》的开放世界渲染:执着于光影表现

腾讯开源手游热更新方案:Unity3D下的XLua技术内幕(一)

……


添加小编微信,发送“程序

即可直接加入GAD程序猿交流基地

获取行业干货资讯,观看大牛分享直播

↓长按添加小编GAD-沫沫


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存